///////////////////////////////////////////////////////////////
//Condition variable wrapper class
//NOTE: not designed for multi-process programming
//
//Sample usage for a generic producer-consumer situation:
//  //Consume one item
//  cv.acquire();
//  while (an_item_is_available() == false)
//      cv.wait();
//  get_an_available_item();
//  cv.release();
//
//  //Produce one item
//  cv.acquire();
//  make_an_item_available();
//  cv.notify();
//  cv.release();
///////////////////////////////////////////////////////////////

#ifndef _CONDITION_H__INCLUDED_
#define _CONDITION_H__INCLUDED_

#include "Utility/Mutex.h"
#include "Utility/ErrorCode.h"
#include <memory>

#ifndef INFINITE
#define INFINITE 0xFFFFFFFF
#endif

namespace nebula { namespace utility {

class ConditionImpl;

class Condition
{
	public:
		Condition();
		Condition(Mutex& mutex);
		~Condition();

		void acquire();
		void release();
		NEBULA_ERROR_CODE wait(unsigned long timeout = INFINITE); //timeout in milliseconds
		void notify();
		void notify_all();

	private:
		std::auto_ptr<ConditionImpl> pImpl;

	private:
		Condition(const Condition& rhs);
		Condition& operator= (const Condition& rhs);
};

}} // namespace nebula::utility

#endif
